﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FireStarter.CodeGeneration.Generator;
using FireStarter.CodeGeneration.Parser;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration.Parser
{

      [TestFixture]
    public class TestIncludeExpressionParser
    {
        private static readonly List<IActionParser> _defaultActionParsers = new List<IActionParser>() { new ValueExpressionParser(), new IfExpressionParser() };

        [Test]
        public void Test_Parse()
        {
            //---------------Set up test pack-------------------
            string includeName = TestUtilsCodeGen.GetRandomString();
            string includeContent = TestUtilsCodeGen.GetRandomString();
            string text = string.Format("INCLUDE({0})", includeName);
            ITemplateLoader loaderStub = new TemplateLoaderStub(includeName, includeContent);
            IParser parser = new IncludeExpressionParser(loaderStub);

            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            TemplateExpression templateExpression = parser.Parse(ref text, _defaultActionParsers);
            //---------------Test Result -----------------------
            ParserTestUtils.AssertExpressionIsInclude(templateExpression);
            IncludeExpression includeExpression = (IncludeExpression) templateExpression;
            ParserTestUtils.AssertExpressionIsLiteral(includeContent, includeExpression.Part);
            Assert.IsNull(includeExpression.Next);
            Assert.AreEqual("", text);
        }


        [Test]
        public void Test_Parse_WithNext()
        {
            //---------------Set up test pack-------------------
            string includeName = TestUtilsCodeGen.GetRandomString();
            string includeContent = TestUtilsCodeGen.GetRandomString();
            string nextText = TestUtilsCodeGen.GetRandomString();
            string text = string.Format("INCLUDE({0}){1}", includeName, nextText);
            ITemplateLoader loaderStub = new TemplateLoaderStub(includeName, includeContent);
            IParser parser = new IncludeExpressionParser(loaderStub);

            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            TemplateExpression templateExpression = parser.Parse(ref text, _defaultActionParsers);
            //---------------Test Result -----------------------
            ParserTestUtils.AssertExpressionIsLiteral(nextText, templateExpression.Next);
        }

        [Test]
        public void Test_IsExpressionMatch()
        {
            //---------------Set up test pack-------------------
            string includeName = TestUtilsCodeGen.GetRandomString();
            string text = string.Format("INCLUDE({0})", includeName);
            IActionParser parser = new IncludeExpressionParser(null);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            bool isExpressionMatch = parser.IsExpressionMatch(text);
            //---------------Test Result -----------------------
            Assert.IsTrue(isExpressionMatch);
        }

        [Test]
        public void Test_IsExpressionMatch_Fails_IfJustInclude()
        {
            //---------------Set up test pack-------------------
            const string text = "INCLUDE";
            IActionParser parser = new IncludeExpressionParser(null);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            bool isExpressionMatch = parser.IsExpressionMatch(text);
            //---------------Test Result -----------------------
            Assert.IsFalse(isExpressionMatch);
        }
    }

    public class TemplateLoaderStub : ITemplateLoader
    {
        private readonly string _includeName;
        private readonly string _includeContent;

        public TemplateLoaderStub(string includeName, string includeContent)
        {
            _includeName = includeName;
            _includeContent = includeContent;
        }

        public string GetTemplateText(string templateName) {
            if (templateName == _includeName) return _includeContent;
            throw new Exception(string.Format("Template name {0} not found in TemplateLoaderStub", templateName));
        }
    }

}
